/** \file    throw_ctrl_signal.cpp
  * \brief   Gives opportunity for console application to react on CTRL events (CTRL+C, Shut down, ...).
  * \date    2002
  * \author  Fedor Chelnokov
  * \version $Header: /home/cscom1r4/cvsroot/cs/mswin/src/throw_ctrl_signal.cpp,v 1.1 2004/01/23 21:29:35 cscom1r4 Exp $
  */

#include "mswin/throw_ctrl_signal.h"
#include "throwWin32Error.h"
#include <windows.h>

namespace mswin {

ctrl_signal::ctrl_signal(unsigned type)
{
	_type = type;
	_altMsg = "control signal ";
	switch (type) {
	case CTRL_C_EVENT:
		_altMsg += "CTRL_C_EVENT";
		break;
	case CTRL_BREAK_EVENT:
		_altMsg += "CTRL_BREAK_EVENT";
		break;
	case CTRL_CLOSE_EVENT:
		_altMsg += "CTRL_CLOSE_EVENT";
		break;
	case CTRL_LOGOFF_EVENT:
		_altMsg += "CTRL_LOGOFF_EVENT";
		break;
	case CTRL_SHUTDOWN_EVENT:
		_altMsg += "CTRL_SHUTDOWN_EVENT";
		break;
	default:
		_altMsg += "of unknown type";
	}
}

static bool  ctrlSignalHappened = false;
static DWORD ctrlSignalType;

BOOL WINAPI ThrowingHandlerRoutine(DWORD dwCtrlType)
{
	ctrlSignalHappened = true;
	ctrlSignalType = dwCtrlType;
//	Sleep(30000);
	return TRUE;
}

catcher_ctrl_signal::catcher_ctrl_signal()
{
	if (!SetConsoleCtrlHandler(ThrowingHandlerRoutine, TRUE))
		throwWin32Error("SetConsoleCtrlHandler");
}

catcher_ctrl_signal::~catcher_ctrl_signal()
{
	if (!SetConsoleCtrlHandler(ThrowingHandlerRoutine, FALSE))
		throwWin32Error("SetConsoleCtrlHandler");
}

void catcher_ctrl_signal::check()
{
	if (ctrlSignalHappened) {
		ctrlSignalHappened = false;
		//LOGOFF not forces process to terminate since not owner user may logoff
		if (ctrlSignalType != CTRL_LOGOFF_EVENT)
			throw ctrl_signal(ctrlSignalType);
	}
}

}
